#ifndef _world_common_hpp_
#define _world_common_hpp_

/** \file Common.hpp
 *  \author Adrian Schweizer
 *  \created  $Do 30 Aug 04:00:24 pm CEST 2007 schwadri@SchwadriComp.local$
 *  \modified $So 28 Okt 05:48:33 pm CET 2007 schwadri@SchwadriLaptop$
 */

#include <boost/serialization/access.hpp>
#include <boost/math/quaternion.hpp>
#include <boost/shared_ptr.hpp>

#include "../core/math/vector.hpp"
#include "../core/math/matrix.hpp"
#include "../core/math/quaternion.hpp"

namespace world {

    /** \brief The type used to represent real numbers in the simulation
     *
     *  All simulation components should use this type instead of float/double
     *  for numerical consistency.
     */
    typedef float   real;

    //type shortcuts
    typedef core::math::vector<real,2>  vector2r;
    typedef core::math::vector<real,3>  vector3r;
    typedef core::math::vector<real,4>  vector4r;
    typedef core::math::vector<real,6>  vector6r;

    typedef core::math::matrix<real,2>  matrix2r;
    typedef core::math::matrix<real,3>  matrix3r;
    typedef core::math::matrix<real,4>  matrix4r;

    typedef boost::math::quaternion<real>   quatr;

} // namespace world


namespace boost { namespace math {

    /** \brief Serialization helper for quaternions*/
    template<class Archive, class T>
        void serialize(Archive & ar, boost::math::quaternion<T>& q, const unsigned int version)
        {
            if(Archive::is_loading::value)
                load(ar,q,version);
            else
                save(ar,q,version);
        }

    template<class Archive, class T>
        void load(Archive & ar, boost::math::quaternion<T>& q, const unsigned int version)
        {
            world::real r1,r2,r3,r4;
            ar & r1;
            ar & r2;
            ar & r3;
            ar & r4;
            q = world::quatr(r1,r2,r3,r4);
        }

    template<class Archive, class T>
        void save(Archive & ar, const boost::math::quaternion<T>& q, const unsigned int version)
        {
            T t = q.R_component_1();
            ar & t;
            t = q.R_component_2();
            ar & t;
            t = q.R_component_3();
            ar & t;
            t = q.R_component_4();
            ar & t;
        }
} }

#endif // _world_common_hpp_
